package proyecto.testcasetool.presentation.details.scenario;

import org.eclipse.core.databinding.ObservablesManager;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.IEMFValueProperty;
import org.eclipse.emf.databinding.edit.EMFEditObservables;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import proyecto.testcasetool.TestcasetoolPackage;
import proyecto.testcasetool.presentation.details.DetailsPage;
import proyecto.testcasetool.presentation.editor.pages.FormLayoutFactory;


public class ParameterDetailPage extends DetailsPage  {

	protected Text txtName;
	protected Text txtDescription;
	protected Text txtCondition;
	
	protected ObservablesManager obsManager;
	protected EMFDataBindingContext bindingContext;
	private ComboViewer typeCombo;
	private ComboViewer dataTypeCombo;
	private ComboViewer validityCombo;
	
	public ParameterDetailPage(FormToolkit toolkit, EditingDomain editingDomain,
			AdapterFactory adapterFactory) {
		super(toolkit, editingDomain, adapterFactory);
		
		bindingContext = new EMFDataBindingContext();
		obsManager = new ObservablesManager();
		
	}
	
	
	@Override
	protected void createDetailsSection(Composite parent) {
		GridLayout gridLayout = (GridLayout) parent.getLayout();
		gridLayout.verticalSpacing = 5;

		Section s = toolkit.createSection(parent, Section.TITLE_BAR);
		s.setText("Parameter details");
		s.setLayoutData(new GridData(GridData.FILL_BOTH));
		s.setLayout(FormLayoutFactory.createDetailsGridLayout(false, 1));
		
		Composite client = toolkit.createComposite(s,SWT.FILL);
		
		s.setClient(client);
		client.setLayout(new GridLayout(2, false));
		toolkit.paintBordersFor(client);
		
		addNameWidget(client);
		
		Label lblDescription = toolkit.createLabel(client, "Description", SWT.NONE);
		txtDescription = toolkit.createText(client, "", SWT.WRAP | SWT.V_SCROLL | SWT.MULTI);
		
		GridData gd_txtDescription = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		gd_txtDescription.heightHint = 80;
		gd_txtDescription.verticalIndent = 10;
		gd_txtDescription.widthHint = 0;
		txtDescription.setLayoutData(gd_txtDescription);
		
		addTypeWidget(client);
		
		addConditionWidget(client);
		
		addDatatypeWidget(client);

		addValidityWidget(client);
	}


	private void addNameWidget(Composite client) {
		Label lblName = toolkit.createLabel(client, "Name", SWT.NONE);
		GridData gd_lblName = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_lblName.verticalIndent = 2;
		lblName.setLayoutData(gd_lblName);
		
		txtName = toolkit.createText(client, "", SWT.NONE);
	
		GridData gd_txtBasicFlowName = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
		gd_txtBasicFlowName.verticalIndent = 2;
		gd_txtBasicFlowName.widthHint = 244;
		txtName.setLayoutData(gd_txtBasicFlowName);
	}
	
	
	private void addTypeWidget(Composite client) {
		Label lblType = toolkit.createLabel(client, "Type", SWT.NONE);
		GridData gd_lblType = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_lblType.verticalIndent = 2;
		lblType.setLayoutData(gd_lblType);
		
		//txtType = toolkit.createText(client, "", SWT.NONE);
	
		typeCombo = new ComboViewer(client);
		typeCombo.setContentProvider(new ArrayContentProvider());
		typeCombo.setLabelProvider(new LabelProvider());
		typeCombo.setInput(new String[]{"input","output", "state"});
		
		GridData gd_txtType = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
		gd_txtType.verticalIndent = 10;
		gd_txtType.widthHint = 200;
		
		
		typeCombo.getCombo().setLayoutData(gd_txtType);
	}
	
	
	private void addConditionWidget(Composite client) {
		Label lblCondition = toolkit.createLabel(client, "Condition", SWT.NONE);
		GridData gd_lblCondition = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_lblCondition.verticalIndent = 2;
		lblCondition.setLayoutData(gd_lblCondition);
		
		txtCondition = toolkit.createText(client, "", SWT.NONE);
	
		GridData gd_txtCondition = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
		gd_txtCondition.verticalIndent = 10;
		gd_txtCondition.widthHint = 200;
		
		txtCondition.setLayoutData(gd_txtCondition);
	}
	
	
	private void addDatatypeWidget(Composite client) {
		Label lblDatatype = toolkit.createLabel(client, "Datatype", SWT.NONE);
		GridData gd_lblDatatype = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_lblDatatype.verticalIndent = 2;
		lblDatatype.setLayoutData(gd_lblDatatype);
		
		dataTypeCombo = new ComboViewer(client);
		dataTypeCombo.setContentProvider(new ArrayContentProvider());
		dataTypeCombo.setLabelProvider(new LabelProvider());
		dataTypeCombo.setInput(new String[]{"integer","string", "unsignedint"});
	
		GridData gd_txtDatatype = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
		gd_txtDatatype.verticalIndent = 10;
		gd_txtDatatype.widthHint = 200;
		
		dataTypeCombo.getCombo().setLayoutData(gd_txtDatatype);
	}
	
	
	private void addValidityWidget(Composite client) {
		Label lblValidity = toolkit.createLabel(client, "Validity", SWT.NONE);
		GridData gd_lblValidity = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_lblValidity.verticalIndent = 2;
		lblValidity.setLayoutData(gd_lblValidity);
		
		validityCombo = new ComboViewer(client);
		validityCombo.setContentProvider(new ArrayContentProvider());
		validityCombo.setLabelProvider(new LabelProvider());
		validityCombo.setInput(new String[]{"valid","invalid"});
	
		GridData gd_txtValidity = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
		gd_txtValidity.verticalIndent = 10;
		gd_txtValidity.widthHint = 200;
		
		validityCombo.getCombo().setLayoutData(gd_txtValidity);
	}
	
	protected void doBinding() {
		
		
		IEMFValueProperty typeProperty = EMFEditProperties
				.value(editingDomain, TestcasetoolPackage.Literals.PARAMETER__TYPE);
		
		IValueProperty selectionProperty = ViewerProperties.singleSelection();
		
		bindingContext.bindValue(selectionProperty.observe(typeCombo),
				typeProperty.observe(eObject), null, null);
		
		IEMFValueProperty dataTypeProperty = EMFEditProperties
				.value(editingDomain, TestcasetoolPackage.Literals.PARAMETER__DATATYPE);
		
		IValueProperty selectionPropertyDataType = ViewerProperties.singleSelection();
		
		bindingContext.bindValue(selectionPropertyDataType.observe(dataTypeCombo),
				dataTypeProperty.observe(eObject), null, null);
		
		
		IEMFValueProperty validityProperty = EMFEditProperties
				.value(editingDomain, TestcasetoolPackage.Literals.PARAMETER__VALIDITY);
		
		IValueProperty selectionPropertyValidity = ViewerProperties.singleSelection();
		
		bindingContext.bindValue(selectionPropertyValidity.observe(validityCombo),
				validityProperty.observe(eObject), null, null);
		
		
		// description
		IObservableValue obsDescFeature = EMFEditObservables
				.observeValue(editingDomain, eObject,
						TestcasetoolPackage.Literals.PARAMETER__DESCRIPTION);

		
		bindingContext.bindValue(SWTObservables.observeText(
				txtDescription, SWT.FocusOut), obsDescFeature);

		//  name
		IObservableValue obsNameFeature = EMFEditObservables
				.observeValue(editingDomain, eObject,
						TestcasetoolPackage.Literals.PARAMETER__NAME);

		bindingContext.bindValue(
				SWTObservables.observeDelayedValue(400, SWTObservables
						.observeText(txtName, SWT.Modify)),
				obsNameFeature);
		
		
		// condition
		IObservableValue obsConditionFeature = EMFEditObservables
				.observeValue(editingDomain, eObject,
						TestcasetoolPackage.Literals.PARAMETER__CONDITION);

		bindingContext.bindValue(
				SWTObservables.observeText(
						txtCondition, SWT.FocusOut),
				obsConditionFeature);
		
		// datatype
		
		obsManager.addObservable(obsConditionFeature);
		obsManager.addObservable(obsNameFeature);
		obsManager.addObservable(obsDescFeature);
	}
	
	public void selectionChanged(IFormPart part, ISelection selection) {
		// controlar que sea la part que esto esperando!!!!
		if (!(selection instanceof IStructuredSelection)) {
			return;
		}
		EObject newEObject = getEObjectFromSelection(selection);
		if (newEObject != null && newEObject != eObject) {
			eObject = newEObject;
			if (eObject != null) {
				
				doBinding();
				
			}
		}
	}

	
	@Override
	public void dispose() {
		super.dispose();
		obsManager.dispose();
	}
}
